<template>
  <div class="calender_layout">
    <div class="calender_item" v-for="calendar in calendarData" :key="calendar.year">
      <div class="calender_title">
        {{ calendar.year }}年{{ calendar.month }}
      </div>
      <div class="calender_week">
        <div class="week_item" v-for="(item, weekIndex) in weekText" :key="weekIndex"
          :class="{ week2: weekIndex == 0 || weekIndex == 6 }">
          {{ item }}
        </div>
      </div>
      <div class="calender_day">
        <div v-for="(month, mIndex) in calendar.date" :key="mIndex" @click="select(month)" :class="{
          date_item: true,
          past_time: month.isPastTime,
          checked: month.checked,
        }">
          <div>{{ month.day }}</div>
          <div v-if="props.del && !month.isPastTime && month.isCurrentMonth && month.checked" class="del" @click.stop="del(month)">
            x
          </div>
        </div>
      </div>
    </div>
  </div>
</template>
<script setup>
import { ref, defineProps, defineEmits, defineExpose, watch } from "vue";

const props = defineProps({
  number: { type: Number, default: 3 },
  del: { type: Boolean, default: true }
});
const emit = defineEmits(["select", "del"]);

const weekText = ["日", "一", "二", "三", "四", "五", "六"];

//每月最大天数
const _monthMaxDay = [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31];

/**
 * 获取指定月份的最大天数
 * @param {*} month 月份 从0开始
 */
function monthMaxDay(year, month) {
  //2月判断是否是闰年
  if (
    month == 1 &&
    ((year % 4 === 0 && year % 100 !== 0) || year % 400 === 0)
  ) {
    return 28;
  } else {
    return _monthMaxDay[month];
  }
}

const nowDate = new Date();

function pastTime(year, month, day) {
  if (
    nowDate.getFullYear() >= year &&
    nowDate.getMonth() + 1 >= month &&
    nowDate.getDate() > day
  ) {
    return true;
  } else {
    return false;
  }
}

function isNotNull(value) {
  return value != null && value != undefined;
}

/**
 * 判断两个日期是否相同
 */
function dateEquals(date1, date2) {
  return (
    date1.year == date2.year &&
    date1.month == date2.month &&
    date1.day == date2.day
  );
}

/**
 * 计算两个日期相隔天数
 */
function getDaysBetween(date1, date2) {
  var startDate = new Date(date1.year, date1.month - 1, date1.day);
  var endDate = new Date(date2.year, date2.month - 1, date2.day);
  var days = (endDate - startDate) / (1 * 24 * 60 * 60 * 1000);
  return days;
}

/**
 * 获取指定月份1日星期几
 * @param {*} month 月份 从0开始
 */
function monthFirstWeek(year, month) {
  return new Date(year, month, 1).getDay();
}

/**
 * 创建月数据
 * @param {*} month 月份 从1开始
 */
function createMonth(year, month) {
  const monthNum = month - 1;
  const week = monthFirstWeek(year, monthNum);
  const maxDay = monthMaxDay(year, monthNum);

  var dates = [];
  var weekindex = week;

  //根据当前月第一天星期几，用上个月天数补全空白
  for (let i = 0; i < week; i++) {
    dates.push({
      isCurrentMonth: false,
      isEnd: false,
      checked: false,
    });
  }
  for (let i = 1; i <= maxDay; i++) {
    let isEnd = false;
    if (weekindex % 7 == 6) {
      isEnd = true;
    }
    dates.push({
      isCurrentMonth: true,
      isPastTime: pastTime(year, month, i),
      isEnd: isEnd,
      year: year,
      month: monthNum + 1,
      day: i,
      checked: false,
    });
    weekindex++;
  }
  //剩余格子补全
  const remainingDay = 42 - dates.length;
  for (let i = 0; i < remainingDay; i++) {
    let isEnd = false;
    if (weekindex % 7 == 6) {
      isEnd = true;
    }
    dates.push({
      isCurrentMonth: false,
      isEnd: isEnd,
      checked: false,
    });
    weekindex++;
  }

  return {
    year: year,
    month: month,
    date: dates,
  };
}

function createCalender(num) {
  var year = nowDate.getFullYear();
  var month = nowDate.getMonth() + 1;
  var calendar = [];
  for (let index = 0; index < num; index++) {
    calendar.push(createMonth(year, month));
    if (month == 12) {
      year++;
      month = 1;
    } else {
      month++;
    }
  }
  calendarData.value = calendar;
  // console.log(calendar)
}

const calendarData = ref([]);
var checkedData = [];
function setChecked(targetDate) {
  checkedData = targetDate;
  for (const calendar of calendarData.value) {
    for (const month of calendar.date) {
      month.checked = false;
      if (!month.isCurrentMonth || month.isPastTime) {
        continue;
      }
      for (const target of targetDate) {
        if (
          dateEquals(
            {
              year: target.dateSrc.getFullYear(),
              month: target.dateSrc.getMonth() + 1,
              day: target.dateSrc.getDate(),
            },
            month
          )
        ) {
          month.checked = true;
        }
      }
    }
  }
}

createCalender(props.number);

watch(
  () => props.number,
  (val) => {
    createCalender(val);
    setChecked(checkedData);
  }
);

function select(data) {
  if (data.day != null && !data.isPastTime) {
    emit("select", data, (res) => {
      if (res) {
        if (!data.checked) {
          data.checked = true;
        }
      }
    });
  }
}

function del(data) {
  emit("del", data);
  data.checked = false;
}

defineExpose({ setChecked });
</script>
<style lang="scss" scoped>
.calender_layout {
  display: grid;
  grid-template-columns: repeat(3, 1fr);

  .calender_item {
    margin: 8px;
    padding: 8px;
    border: solid #dcdfe6 1px;

    .calender_title {
      margin: 6px 0;
      text-align: center;
      font-weight: bold;
    }
  }
}

.calender_week {
  display: grid;
  grid-template-columns: repeat(7, 1fr);
  text-align: center;
  border-bottom: solid #dcdfe6 1px;

  .week_item {
    padding: 10px;
  }
}

.calender_day {
  display: grid;
  grid-template-columns: repeat(7, 1fr);
  text-align: center;

  .date_item {
    position: relative;
    text-align: center;
    line-height: 45px;
    height: 45px;
    cursor: pointer;

    .del {
      position: absolute;
      top: -10px;
      right: -10px;
      display: flex;
      opacity: 0;
      justify-content: center;
      align-items: center;
      scale: 0.7;
      font-size: 25px;
      width: 30px;
      height: 30px;
      font-weight: normal;
      border-radius: 15px;
      background: #f00;
      color: #fff;
    }

    &:hover {
      .del {
        opacity: 1;
      }
    }
  }

  .checked {
    font-weight: bold;
    color: #409eff;
  }

  .past_time {
    cursor: no-drop !important;
    color: #777;
  }
}

.week2 {
  color: #409eff;
}
</style>